package com.evil.activiti.interseptor;

import com.evil.activiti.pojo.bo.UserBO;
import com.evil.activiti.util.ActivityUtil;
import com.evil.common.core.constant.AppConstant;
import com.evil.common.account.dto.user.UserEnterpriseDTO;
import com.evil.common.core.enums.RCodeEnum;
import com.evil.common.core.exception.BusinessException;
import com.evil.common.core.util.ServletUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.context.SecurityContextImpl;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Collection;

@Slf4j
@Component
public class LoginInterceptor implements HandlerInterceptor {


    @Override
    public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3) throws Exception {
    }

    @Override
    public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3) throws Exception {
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object arg2) throws Exception {
        String enterpriseIdStr = ServletUtils.getRequest().getHeader(AppConstant.HEADER_ENTERPRISE_ID);
        String userIdStr = ServletUtils.getRequest().getHeader(AppConstant.HEADER_USER_ID);
        if (StringUtils.isBlank(enterpriseIdStr) || StringUtils.isBlank(userIdStr)) {
            throw new BusinessException(RCodeEnum.ERROR_UNAUTHENTICATED);
        }
        Long enterpriseId = Long.valueOf(enterpriseIdStr);
        Long userId = Long.valueOf(userIdStr);
        String username = ActivityUtil.toActivitiLoginUser(new UserEnterpriseDTO(enterpriseId, userId));
        UserBO user = new UserBO(username);

        SecurityContextHolder.setContext(new SecurityContextImpl(new Authentication() {
            @Override
            public Collection<? extends GrantedAuthority> getAuthorities() {
                return user.getAuthorities();
            }

            @Override
            public Object getCredentials() {
                return null;
            }

            @Override
            public Object getDetails() {
                return user;
            }

            @Override
            public Object getPrincipal() {
                return user;
            }

            @Override
            public boolean isAuthenticated() {
                return true;
            }

            @Override
            public void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException {
            }

            @Override
            public String getName() {
                return user.getUsername();
            }
        }));
        org.activiti.engine.impl.identity.Authentication.setAuthenticatedUserId(username);
        return true;
    }
}
